package com.indusfo.spc.service.impl;

import com.indusfo.spc.exception.GlobalException;
import com.indusfo.spc.exception.ModifyFailedException;
import com.indusfo.spc.exception.ParamsErrorException;
import com.indusfo.spc.mapper.PlanMapper;
import com.indusfo.spc.mapper.UploadMapper;
import com.indusfo.spc.pojo.Datadict;
import com.indusfo.spc.pojo.Plan;
import com.indusfo.spc.pojo.ProcessVer;
import com.indusfo.spc.service.BarCodeRules;
import com.indusfo.spc.service.PlanService;
import com.indusfo.spc.vo.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author louk
 * @date 2019/10/22 9:44
 */
@Service
public class PlanServiceImpl implements PlanService {
    private static final Logger logger = LoggerFactory.getLogger(PlanServiceImpl.class);
    @Resource
    private PlanMapper planMapper;

    @Resource
    private SqlSessionTemplate sqlSessionTemplate;

    @Resource
    private UploadMapper uploadMapper;

    @Resource
    private BarCodeRules barCodeRules;

    private static String LPLAN=null;
    //新增
    @Override
    public JSONObject insertPlan(Plan plan) {
        List<String> calculate = barCodeRules.calculate(12, 1);
        String ruleCode = calculate.get(0);
        plan.setlPlan(ruleCode);
        plan.setlDataState(1);
        //新增任务单默认是1 待发布的状态
        plan.setlExecuteState(1);
        //判断是否为空
        checkParam(plan);
        int insert = planMapper.insert(plan);
        if (insert == 0) {
            throw new ModifyFailedException("数据新增失败！");
        }
        return JSONObject.oK("新增成功！");
    }
    //编辑
    @Override
    public JSONObject updatePlan(Plan plan) {
        Integer productionPlanId = plan.getlProductionPlanId();
        if(productionPlanId==null){
            throw new ModifyFailedException("更新数据id不能为空");
        }
        //判断是否为空
        checkParam(plan);
        int update = planMapper.updatePlan(plan);
        if (update == 0) {
            throw new ModifyFailedException("数据更新失败！");
        }
        return JSONObject.oK("更新成功！");
    }
    //查询
    @Override
    public JSONObject queryPlan(Plan plan) {

        List<Plan> listPlan = null;
        try {
            Integer pagesize = plan.getPagesize();
            Integer pageindex = plan.getPageindex();
            if(pagesize != null && pageindex != null) {
                plan.setIncept(pagesize*(pageindex - 1));
            }
            Integer productionPlanId = plan.getlProductionPlanId();
            if(productionPlanId != null) {  //如果有id,则查询单个产线信息
                Plan plan1 = planMapper.selectByPrimaryKey(productionPlanId);
                listPlan.add(plan1);
            } else{  //查询多个sop管理信息
                listPlan = planMapper.queryPlanList(plan);
            }
            if (listPlan.isEmpty()) {
                return JSONObject.oK("没有查询到相关数据", listPlan, 0);
            }
            //查询分页总记录数
            int count = planMapper.countPlan(plan);
            return JSONObject.oK("查询成功", listPlan, count);
        } catch (GlobalException e) {
            logger.error(e.getMessage(), e);
            return JSONObject.build(403, e.getMessage());
        }
    }
    //删除
    @Override
    public JSONObject deletePlan(Integer[] ids, Integer lDataState,Integer[] lExecuteStateIds) {

        try {
            if(lDataState == null) {
                throw new ParamsErrorException("数据状态不能为空");
            }else if(lDataState != 1 && lDataState != 2 && lDataState != 3) {
                throw new ParamsErrorException("数据状态错误");
            }
            if (ids == null) {
                throw new ParamsErrorException("请选择要删除的数据");
            }
            for (Integer lExecuteStateId : lExecuteStateIds) {
                if(lExecuteStateId!=1){
                    throw new ParamsErrorException("所选任务单中中包含状态为非待发布的任务单,无法删除");
                }
            }
            // 执行存储过程
            int row = planMapper.updateByPrimaryKey(ids,lDataState);
            String msg = "";
            if (row == 0) {
                // 判断传入的数据状态参数lDataState,返回相应信息
                switch (lDataState) {
                    case 1:
                        throw new ModifyFailedException("启用失败");
                    case 2:
                        throw new ModifyFailedException("删除失败");
                    case 3:
                        throw new ModifyFailedException("停用失败");
                    default:
                }
            } else {
                switch (lDataState) {
                    case 1:
                        msg = "启用成功";break;
                    case 2:
                        msg = "删除成功";break;
                    case 3:
                        msg = "停用成功";break;
                    default:
                }
            }
            return JSONObject.oK(msg);
        } catch (GlobalException e) {
            logger.error(e.getMessage(), e);
            return JSONObject.build(403, e.getMessage());
        }
    }
    //状态变更
    @Override
    public JSONObject lExecuteStateChange(Integer[] ids,Integer[] lExecuteStateIds,Integer lExecuteState) {

        try {
            if(lExecuteState == null) {
                return JSONObject.oK("发布状态不能为空");
            }else if(lExecuteState != 1 && lExecuteState != 2 && lExecuteState != 3 && lExecuteState != 4 && lExecuteState != 5) {
                return JSONObject.oK("数据状态错误");
            }
            if (ids == null) {
                return JSONObject.oK("请选择要更改的数据");
            }
            //如完工时，只能查看，其它按钮不能操作
            for (Integer lExecuteStateId : lExecuteStateIds) {
                if(lExecuteStateId==5){
                    return JSONObject.oK("所选任务单中包含已完工,无法进行状态修改");
                }
            }
            //需要对状态修改为暂停时,需要传递当前状态给后台,作为上次状态进行存储
            if(lExecuteState==4 ){
                if(lExecuteStateIds==null){
                    return JSONObject.oK("当前状态未传递");
                }
                SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);//跟上述sql区别
                PlanMapper mapper = sqlSession.getMapper(PlanMapper.class);
                for (int i = 0; i < ids.length; i++) {
                    mapper.updateLastExecuteState(ids[i], lExecuteStateIds[i]);
                }
                sqlSession.commit();
                sqlSession.clearCache();

            }
            //当状态已发布或生产中、暂停、已完工，不能重新发布，
            if(lExecuteState==2){
                for (Integer lExecuteStateId : lExecuteStateIds) {
                    if(lExecuteStateId==3 || lExecuteStateId==4 || lExecuteStateId==5){
                        return JSONObject.oK("所选择的任务单中的有状态为已发布或生产中、暂停、已完工的任务单无法进行发布");
                    }
                }
            }
            //点击恢复按钮时，状态需要恢复到上次状态
            if(lExecuteState==3){
                for (Integer lExecuteStateId : lExecuteStateIds) {
                    if(lExecuteStateId!=4){
                        return JSONObject.oK("只有在任务单状态暂停的情况才可以恢复");
                    }
                }
                int updateByLastExecuteState = planMapper.updateByLastExecuteState(ids);
                if(updateByLastExecuteState==0){
                    return JSONObject.oK("恢复失败");
                }
                return JSONObject.oK("恢复成功");
            }
            // 执行存储过程
            int row = planMapper.lExecuteStateChange(ids,lExecuteState);
            if(row==0){
                return JSONObject.oK("更新失败");
            }
            return JSONObject.oK("更新成功");
        } catch (GlobalException e) {
            logger.error(e.getMessage(), e);
            return JSONObject.build(403, e.getMessage());
        }
    }
    //获取版本
    @Override
    public JSONObject getVersion(Integer lProduct) {
        if(lProduct==null){
            throw new ParamsErrorException("车间ID为空");
        }
        ProcessVer version = planMapper.getVersion(lProduct);
        return JSONObject.oK("查询成功", version, 1);
    }


    private void checkParam(Plan plan) {
        Date overDate;
        Date startDate;
        Date actualStartDate=new Date();
        Date actualFinishDate=new Date();
        //创建日期
        String createTime = plan.getdCreateTime();
        //产品id
        Integer lProduct = plan.getlProduct();
        //订单类型
        Integer orderType = plan.getOrderType();
        //版本号
        Integer versionNumber = plan.getVersionNumber();
        //产线id
        Integer productionLineId = plan.getlProductionLineId();
        //班次id
        Integer classes = plan.getlClasses();
        //开始时间
        String startTime = plan.getdStartTime();
        String overTime = plan.getdOverTime();

        if(plan.getVcRemark()!=null && plan.getVcRemark().length()>100){
            throw new ParamsErrorException("说明超过规定长度");
        }
        if(lProduct==null) {
            throw new ParamsErrorException("物料编码不能为空");
        }
        if (orderType==null) {
            throw new ParamsErrorException("订单类型不能为空");
        }

        if (versionNumber==null) {
            throw new ParamsErrorException("版本号不能为空");
        }
        if (productionLineId==null) {
            throw new ParamsErrorException("车间产线不能为空");
        }
        if (classes==null) {
            throw new ParamsErrorException("班次不能为空");
        }
        if(overTime==null){
            throw new ParamsErrorException("结束时间不能为空");
        }
        if(startTime==null){
            throw new ParamsErrorException("开始时间不能为空");
        }
        try {
            startDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTime);

        } catch (Exception exception) {
            throw new ParamsErrorException("开始时间格式不正确");
        }
        try {
            overDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(overTime);

        } catch (Exception exception) {
            throw new ParamsErrorException("结束时间格式不正确");
        }
        if (startDate.getTime()>overDate.getTime()) {
            throw new ParamsErrorException("开始时间不能大于结束时间");
        }
        if(plan.getActualStartTime()!=null){
            try {
                actualStartDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTime);
            } catch (Exception exception) {
                throw new ParamsErrorException("实际开始时间格式不正确");
            }
        }
        if(plan.getActualEndTime()!=null){
            try {
                actualFinishDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTime);
            } catch (Exception exception) {
                throw new ParamsErrorException("实际结束时间格式不正确");
            }
        }
        if(plan.getActualStartTime()!=null && plan.getActualEndTime()!=null){
            if (actualStartDate.getTime()>actualFinishDate.getTime()) {
                throw new ParamsErrorException("实际开始时间不能大于实际结束时间");
            }
        }
    }
    @Override
    public String checkExcelContent(Plan plan) {
        if(LPLAN==null){
            getLPlan();
        }
        plan.setlPlan(LPLAN);
        Date overDate;
        Date startDate;
        //订单类型名称
        String orderTypeName = plan.getOrderTypeName();
        //版本号
        String vcVersion = plan.getVcVersion();
        //产线名称
        String vcProductionLineName = plan.getVcProductionLineName();
        //班次名称
        String vcClasses = plan.getVcClasses();
        //计划数量
        Integer lPlanNumber = plan.getlPlanNumber();
        //物料名称/产品名称
        String vcProjectName = plan.getVcProjectName();
        //制单人
        String vcUserName = plan.getVcUserName();
        //开始时间
        String startTime = plan.getdStartTime();
        //结束时间
        String overTime = plan.getdOverTime();
        if(StringUtils.isBlank(orderTypeName) && StringUtils.isBlank(vcVersion) && StringUtils.isBlank(vcProductionLineName) && StringUtils.isBlank(vcClasses) && StringUtils.isBlank(lPlanNumber.toString()) &&
                StringUtils.isBlank(vcProjectName) && StringUtils.isBlank(vcUserName) && StringUtils.isBlank(startTime) && StringUtils.isBlank(overTime)){
            return "该行数据为空(原因:清空行内容时未清空彻底/未输入)";
        }
        if(plan.getVcRemark()!=null && plan.getVcRemark().length()>100){
            return "说明超过规定长度";
        }
        if(orderTypeName==null) {
            return "订单类型名称为空";
        }
        Map<String, Datadict> orderTypeMap = uploadMapper.queryType(101012);
        if(!orderTypeMap.containsKey(orderTypeName)){
            return "订单类型名称填写不规范/错误";
        }
        Datadict orderTypeTdatadict = orderTypeMap.get(orderTypeName);
        plan.setOrderType(orderTypeTdatadict.getItemId());
        if (vcVersion==null) {
            return "版本号为空";
        }
        if (vcProductionLineName==null) {
            return "产线名称为空";
        }
        if (vcClasses==null) {
            return "班次名称为空";
        }
        if (lPlanNumber==null) {
            return "计划数量为空";
        }
        if(overTime==null){
            return "结束时间为空";
        }
        if(startTime==null){
            return "开始时间为空";
        }
        if(vcProjectName==null){
            return "产品名称为空";
        }
        if(vcUserName==null){
            return "制单人为空";
        }

        try {
            startDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTime);
        } catch (Exception exception) {
            return "开始时间格式不正确";
        }
        try {
            overDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(overTime);

        } catch (Exception exception) {
            return "结束时间格式不正确";
        }
        if (startDate.getTime()>overDate.getTime()) {
            return "开始时间不能大于结束时间";
        }

        return null;
    }

    private void getLPlan(){
        List<String> calculate = barCodeRules.calculate(12, 1);
        LPLAN = calculate.get(0);
    }

}
